﻿@namespace BlazorDemos.Shared
@implements IDisposable;

@inject NavigationManager UriHelper;
@inject SampleService SampleService;

<div class="@classNames" role="list">
    <div class="@SampleUtils.CONTENT">
        <ul class="@SampleUtils.LIST_UL_CLASS" role="list">
            @if (groupData != null)
            {
                @foreach (var group in @groupData)
                {
                    var groupName = group.FirstOrDefault().Category;
                    if (GroupTemplate != null && groupName != null && this.groupList != null && !this.groupList.Contains(groupName))
                    {
                        this.groupList.Add(groupName);
                        <li class="@SampleUtils.LIST_LI_GROUP_CLASS" role="group">
                            @GroupTemplate(group.FirstOrDefault())
                        </li>
                    }
                    foreach (var item in group)
                    {
                        if (Template != null)
                        {
                            var liClass = SampleUtils.LIST_LI_CLASS;
                            if (EqualityComparer<Sample>.Default.Equals(item, selectedItem))
                            {
                                liClass = SampleUtils.AddClass(liClass, SampleUtils.LIST_ACTIVE);
                            }
                            <li class="@liClass" role="listitem" @onclick="@(async () => { await OnSelection(item); })">
                                @Template(item)
                            </li>
                        }
                    }
                }
            }
        </ul>
    </div>
</div>

@code {
    private Sample selectedItem;
    private List<string> groupList;
    private List<List<Sample>> groupData { get; set; }
    private string classNames = SampleUtils.LIST_CLASS;

    /// <summary>
    /// Child content of ListComponent.
    /// </summary>
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    /// <summary>
    /// Specifies the datasource of list component.
    /// </summary>
    [Parameter]
    public IEnumerable<Sample> DataSource { get; set; }

    /// <summary>
    /// Specifies the group template of list component.
    /// </summary>
    [Parameter]
    public RenderFragment<Sample> GroupTemplate { get; set; }

    /// <summary>
    /// Specifies the item template of list component.
    /// </summary>
    [Parameter]
    public RenderFragment<Sample> Template { get; set; }

    /// <summary>
    /// Triggers event callback on item selection.
    /// </summary>
    [Parameter]
    public EventCallback<Sample> OnSelectList { get; set; }

    /// <summary>
    /// Set selection to the list component based on given item.
    /// </summary>
    /// <param name="item">Item that need to be selected.</param>
    public void SelectItem(Sample item)
    {
        selectedItem = item;
        this.groupList = new List<string>();
        StateHasChanged();
    }

    // Item click handler
    private async Task OnSelection(Sample item)
    {
        if (this.OnSelectList.HasDelegate)
        {
            selectedItem = item;
            await this.OnSelectList.InvokeAsync(item);
        }
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        this.groupList = new List<string>();
        // Set selection to the intial rendering.
        if (this.DataSource.Count() > 0)
        {
            groupData = this.DataSource.GroupBy(g => g.Category).Select(s => s.ToList()).ToList();
            if (selectedItem == null)
            {
                SampleService.Update(UriHelper);
            }
            selectedItem = SampleService.SampleInfo;
        }
    }

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        this.groupList = null;
    }

    public void Dispose()
    {
        selectedItem = null;
        groupList = null;
        groupData = null;
        DataSource = null;
    }
}
